﻿#region Usings
using System;
using System.Diagnostics;
using System.Threading;

using BK.Model;
using BK.Repositories.Abstract;
using BK.Repositories.EF;

using Ninject;
using Ninject.Modules;
#endregion

namespace BK.Repositories.Factory
{
    public static class RepositoryFactory
    {
        #region Readonly & Static Fields
        private static readonly IKernel _kernel;
        #endregion

        static RepositoryFactory()
        {
            _kernel = new StandardKernel(new ConfigModule());
        }

        #region Class Methods
        public static TRepository Get<TRepository>() where TRepository : IRepository
        {
            return _kernel.Get<TRepository>();
        }
        #endregion

        #region Nested type: ConfigModule
        private class ConfigModule : NinjectModule
        {
            private BkDataContext DataContext
            {
                get
                {
                    string KEY = GetType().FullName;
                    Debug.Assert(KEY != null, "KEY != null");
                    LocalDataStoreSlot dataSlot = Thread.GetNamedDataSlot(KEY);

                    BkDataContext bkDataContext = (BkDataContext) Thread.GetData(dataSlot);

                    if (bkDataContext == null)
                    {
                        bkDataContext = new BkDataContext();
                        Thread.SetData(dataSlot, bkDataContext);
                    }

                    return bkDataContext;
                }
            }

            #region Instance Methods
            public override void Load()
            {
                const string DATA_CONTEXT_PARAM_NAME = "dataContext";
                Bind<IUsersRepository>().To<UsersRepository>().WithConstructorArgument(DATA_CONTEXT_PARAM_NAME, DataContext);
                Bind<IAccountsRepository>().To<AccountsRepository>().WithConstructorArgument(DATA_CONTEXT_PARAM_NAME, DataContext);
                Bind<IBestExpensesFilesRepository>().To<BestExpensesFilesRepository>().WithConstructorArgument(DATA_CONTEXT_PARAM_NAME, DataContext);
                Bind<IBestExpensesRepository>().To<BestExpensesRepository>().WithConstructorArgument(DATA_CONTEXT_PARAM_NAME, DataContext);
                Bind<ICategoriesRepository>().To<CategoriesRepository>().WithConstructorArgument(DATA_CONTEXT_PARAM_NAME, DataContext);
                Bind<ICurrenciesRepository>().To<CurrenciesRepository>().WithConstructorArgument(DATA_CONTEXT_PARAM_NAME, DataContext);
                Bind<IImportStatusesRepository>().To<ImportStatusesRepository>().WithConstructorArgument(DATA_CONTEXT_PARAM_NAME, DataContext);
                Bind<ITargetsRepository>().To<TargetsRepository>().WithConstructorArgument(DATA_CONTEXT_PARAM_NAME, DataContext);
                Bind<IPaymentsRepository>().To<PaymentsRepository>().WithConstructorArgument(DATA_CONTEXT_PARAM_NAME, DataContext);
                Bind<IFinancistoFilesRepository>().To<FinancistoFilesRepository>().WithConstructorArgument(DATA_CONTEXT_PARAM_NAME, DataContext);
                Bind<IFinancistoExpensesRepository>().To<FinancistoExpensesRepository>().WithConstructorArgument(DATA_CONTEXT_PARAM_NAME, DataContext);
            }
            #endregion
        }
        #endregion
    }
}